Skip to content

[X86] Try to shrink i64 compares if the input has enough sign bits #149719

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Aug 2, 2025

Conversation

AZero13
Copy link
Contributor

@AZero13 AZero13 commented Jul 20, 2025

If there are enough sign bits in a 64 bit value, we can just compare the bottom 32 bits.

@llvmbot
Copy link
Member

llvmbot commented Jul 20, 2025

@llvm/pr-subscribers-backend-x86

Author: AZero13 (AZero13)

Changes

We have to check for SIGN_EXT because unlike the zero_ext version, DAG cannot just automatically know the top bits are 0, unlike in zero extension (hence the name zero extension).


Full diff: https://github.com/llvm/llvm-project/pull/149719.diff

2 Files Affected:

  • (modified) llvm/lib/Target/X86/X86ISelLowering.cpp (+15-1)
  • (modified) llvm/test/CodeGen/X86/cmp.ll (+12)
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index d91ea1ea1bb1b..5d5d0c23376c7 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -23479,7 +23479,6 @@ static SDValue EmitCmp(SDValue Op0, SDValue Op1, X86::CondCode X86CC,
   }
 
   // Try to shrink i64 compares if the input has enough zero bits.
-  // TODO: Add sign-bits equivalent for isX86CCSigned(X86CC)?
   if (CmpVT == MVT::i64 && !isX86CCSigned(X86CC) &&
       Op0.hasOneUse() && // Hacky way to not break CSE opportunities with sub.
       DAG.MaskedValueIsZero(Op1, APInt::getHighBitsSet(64, 32)) &&
@@ -23489,6 +23488,21 @@ static SDValue EmitCmp(SDValue Op0, SDValue Op1, X86::CondCode X86CC,
     Op1 = DAG.getNode(ISD::TRUNCATE, dl, CmpVT, Op1);
   }
 
+  // Try to shrink signed i64 compares if the input has enough one bits.
+  // Or the input is sign extended from a 32-bit value.
+  if (CmpVT == MVT::i64 && isX86CCSigned(X86CC) &&
+      Op0.hasOneUse() && // Hacky way to not break CSE opportunities with sub.
+      (DAG.MaskedValueIsAllOnes(Op1, APInt::getHighBitsSet(64, 32)) ||
+       Op1.getOpcode() == ISD::SIGN_EXTEND ||
+       Op1.getOpcode() == ISD::SIGN_EXTEND_INREG) &&
+      (DAG.MaskedValueIsAllOnes(Op0, APInt::getHighBitsSet(64, 32)) ||
+       Op0.getOpcode() == ISD::SIGN_EXTEND ||
+       Op0.getOpcode() == ISD::SIGN_EXTEND_INREG)) {
+    CmpVT = MVT::i32;
+    Op0 = DAG.getNode(ISD::TRUNCATE, dl, CmpVT, Op0);
+    Op1 = DAG.getNode(ISD::TRUNCATE, dl, CmpVT, Op1);
+  }
+
   // 0-x == y --> x+y == 0
   // 0-x != y --> x+y != 0
   if (Op0.getOpcode() == ISD::SUB && isNullConstant(Op0.getOperand(0)) &&
diff --git a/llvm/test/CodeGen/X86/cmp.ll b/llvm/test/CodeGen/X86/cmp.ll
index f3e141740b287..d71a7adafc652 100644
--- a/llvm/test/CodeGen/X86/cmp.ll
+++ b/llvm/test/CodeGen/X86/cmp.ll
@@ -956,3 +956,15 @@ define i1 @fold_test_and_with_chain(ptr %x, ptr %y, i32 %z) {
   store i32 %z, ptr %y
   ret i1 %c
 }
+
+define i1 @sext_mask(i32 %a) {
+; CHECK-LABEL: sext_mask:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    cmpl $-523, %edi # encoding: [0x81,0xff,0xf5,0xfd,0xff,0xff]
+; CHECK-NEXT:    # imm = 0xFDF5
+; CHECK-NEXT:    setl %al # encoding: [0x0f,0x9c,0xc0]
+; CHECK-NEXT:    retq # encoding: [0xc3]
+  %a64 = sext i32 %a to i64
+  %v1 = icmp slt i64 %a64, -523
+  ret i1 %v1
+}

@AZero13 AZero13 requested a review from RKSimon July 20, 2025 16:55
@AZero13 AZero13 requested review from RKSimon and topperc July 23, 2025 15:17
@AZero13 AZero13 requested a review from RKSimon July 23, 2025 18:57
So that equality comparisons also work.
@AZero13
Copy link
Contributor Author

AZero13 commented Jul 26, 2025

@topperc Thoughts?

@AZero13 AZero13 changed the title [X86] Try to shrink signed i64 compares if the input has enough one bits [X86] Try to shrink i64 compares if the input has enough one bits Jul 27, 2025
@AZero13 AZero13 requested a review from topperc July 27, 2025 16:34
@RKSimon
Copy link
Collaborator

RKSimon commented Jul 28, 2025

Shouldn't "if the input has enough one bits" be "if the input has enough sign bits"?

@AZero13 AZero13 changed the title [X86] Try to shrink i64 compares if the input has enough one bits [X86] Try to shrink i64 compares if the input has enough sign bits Jul 28, 2025
@AZero13
Copy link
Contributor Author

AZero13 commented Jul 28, 2025

Shouldn't "if the input has enough one bits" be "if the input has enough sign bits"?

Done!

Copy link
Collaborator

@topperc topperc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@AZero13
Copy link
Contributor Author

AZero13 commented Jul 28, 2025

Thank you. @topperc Can we please merge?

@RKSimon
Copy link
Collaborator

RKSimon commented Jul 29, 2025

Please can you rewrite the summary description.

@AZero13
Copy link
Contributor Author

AZero13 commented Jul 29, 2025

@RKSimon okay done

@AZero13 AZero13 requested a review from RKSimon August 1, 2025 14:34
Copy link
Collaborator

@RKSimon RKSimon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@RKSimon RKSimon merged commit 8e9e38a into llvm:main Aug 2, 2025
9 checks passed
@AZero13 AZero13 deleted the enhanced branch August 2, 2025 21:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants